package com.tang.lts.core.store;

import com.tang.lts.core.store.dbutils.DbRunner;
import com.tang.lts.core.store.dbutils.ResultSetHandler;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * @author Tang
 * @classname SqlTemplateImpl
 * @description [  ]
 * @date 2022/5/6 14:42
 */
public class SqlTemplateImpl implements SqlTemplate {

    private DataSource dataSource;

    private DbRunner dbRunner = new DbRunner();

    public SqlTemplateImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public <T> T execute(boolean isReadOnly, SqlExecutor<T> sqlExecutor) {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            return sqlExecutor.run(connection);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public void createTable(String sql) {

    }

    @Override
    public int insert(String sql, Object... ags) {
        return execute(false,connection -> {
            return insert(connection, sql, ags);
        });
    }

    public int insert(Connection connection,String sql, Object... ags) {
        return dbRunner.insert(connection,sql,ags);
    }

    @Override
    public <T> T query(String sql) {
        return null;
    }

    @Override
    public <T> T query(String sql, ResultSetHandler<T> rSHandler, Object... args) {
        return execute(false,connection -> {
            return query(connection, sql, rSHandler, args);
        });
    }

    public <T> T query(Connection connection,String sql, ResultSetHandler<T> rSHandler, Object... args) {
        return dbRunner.query(connection, sql, rSHandler, args);
    }

    @Override
    public <T> T executeInTransaction(SqlExecutor<T> sqlExecutor) {
        Connection currentCon = null;
        try {
            currentCon = TxConnectionFactory.getCurrentCon();
            return sqlExecutor.run(currentCon);
        }finally {
            TxConnectionFactory.closeTx(currentCon);
        }
    }
}